// Compile with
// gcc -Wall -fPIC -shared -D_GNU_SOURCE -o libprepost.so libprepost.c -ldl

#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>

#ifndef ELFCLASS32
#ifdef __KERNEL__
#include <linux/elf.h>
#else	
#include <elf.h>
#endif
#endif

#ifndef ELFCLASSM
#define ELFCLASSM ELF_CLASS
#endif
 
#ifndef ElfW
# if ELFCLASSM == ELFCLASS32
#  define ElfW(x)  Elf32_ ## x
#  define ELFW(x)  ELF32_ ## x
# else
#  define ElfW(x)  Elf64_ ## x
#  define ELFW(x)  ELF64_ ## x
# endif
#endif

typedef int (*main_t)(int, char **, char **);
main_t realmain;

int exitfunc()
{
    printf("ENDED\n");
}

int wrap_main(int argc, char **argv, char **environ)
{
        printf("STARTING\n");
        atexit(exitfunc);

        (*realmain)(argc, argv, environ);
}
        
int __libc_start_main(main_t main,
                      int argc,
                      char *__unbounded *__unbounded ubp_av,
                      ElfW(auxv_t) *__unbounded auxvec,
                      __typeof (main) init,
                      void (*fini) (void),
                      void (*rtld_fini) (void), void *__unbounded
                      stack_end)
{
        void *libc;
        int (*libc_start_main)(main_t main,
                               int,
                               char *__unbounded *__unbounded,
                               ElfW(auxv_t) *,
                               __typeof (main),
                               void (*fini) (void),
                               void (*rtld_fini) (void),
                               void *__unbounded stack_end);

        libc_start_main = dlsym(RTLD_NEXT, "__libc_start_main");
        if (!libc_start_main)
                ERROR("Failed: %s\n", dlerror());

        realmain = main;
        return (*libc_start_main)(wrap_main, argc, ubp_av, auxvec,
        init, fini, rtld_fini, stack_end);
}


